package com.savard.controller;

import com.micheldalal.x10.CM17A;
import com.savard.util.SerialPortUtil;
import gnu.io.PortInUseException;
import gnu.io.RXTXPort;
import gnu.io.SerialPort;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Collection;
import java.util.concurrent.locks.ReentrantLock;

/**
 * User: csavard
 * Date: 13-03-16
 */
@Controller
@RequestMapping("/x10")
public class X10Controller {
    private Log log = LogFactory.getLog(X10Controller.class);

    private RuntimeException initException;

    private static CM17A cm17A;
    private static ReentrantLock lock = new ReentrantLock();

    @PostConstruct
    public void init() {
        try {
           /* Collection<SerialPort> serialPorts = SerialPortUtil.getSerialPorts();
            SerialPort serialPort = serialPorts.iterator().next();

            log.info("Connect on port: " + serialPort.getName());*/
            lock.lock();
            try {
                if (cm17A == null) {
                    log.info("Connect on port: " + "/dev/ttyS0");
                    cm17A = new CM17A(new RXTXPort("/dev/ttyS0"));
                }
            } finally {
                lock.unlock();
            }
        } catch (Throwable e) {
            log.error("No serial port detected", e);
            initException = new RuntimeException("No serial port detected", e);
        }


    }

    @PreDestroy
    public void destroy() {
        lock.lock();
        try {
            if (cm17A != null) {
                cm17A.getSerialPort().close();
                cm17A = null;
            }
        } finally {
            lock.unlock();
        }
    }


    @RequestMapping(value = "/set", method = RequestMethod.GET)
    public void setState(Character house, Integer unit, Boolean state) {
        if (initException != null) {
            throw initException;
        }

        log.info("Set House: " + house + ", Unit: " + unit + " = " + state);
        cm17A.setState(house, unit, state);
    }
}
